#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <algorithm>
#include<thread>
#include <ctime>
#include <ratio>
#include <chrono>
using namespace std;


//int main(){
//	FILE* fout = fopen("Test.txt", "r");
//	cout << fout << endl;
//	cout << errno << endl;
//	perror("fopen fail");
//
//	return 0;
//}


// —————— 抛异常初识 ———————— 

//// 模板如下：
//try{
//	// 保护的标识代码
//}
//catch (ExceptionName e1){
//	// catch 块
//}
//catch (ExceptionName e2){
//	// catch 块
//}
//catch (ExceptionName eN){
//	// catch 块
//}
////catch...

//double Division() {
//	int a, b;
//	cin >> a >> b;
//	// 当b == 0时抛出异常
//	if (b == 0) {
//		throw "除 0 错误！";//抛出异常,异常的描述
//		/*string s("除 0 错误！");
//		throw s;*/
//	}
//	else {
//		return ((double)a / (double)b);
//	}
//}
//
//int main(){
//	try {
//		cout << Division() << endl;
//	}
//	//捕获异常
//	catch (const char* a) {
//		cout << a << endl;
//	}
//	catch (...) {
//		cout << "unknown exception" << endl;
//	}
//	return 0;
//}


//// —————————— —————————————————— 
//double Division(int a, int b){
//	// 当b == 0时抛出异常
//	if (b == 0){
//		//throw "Division by zero condition!";
//		string s("Division by zero condition!");
//		throw s;
//	}
//	else{
//		return ((double)a / (double)b);
//	}
//}
//
//void Func(){
//	int len, time;
//	cin >> len >> time;
//	cout << Division(len, time) << endl;
//	try{
//		cout << Division(len, time) << endl;
//	}
//	//捕获异常
//	catch (size_t x){ //类型必须严格匹配，隐式类型转换也不行
//		cout << x << endl;
//	}
//	catch (const char* errmsg){ //注释掉这个就打印unkown exception
//		cout << errmsg << endl;
//	}
//	cout << "xxxxxxxxxxxxxxxxxxxxx" << endl;
//}
//
//int main(){
//	//异常只有在 try_catch中才可以被捕获
//	try {
//		Func();
//	}
//	// 在下面抛出的对象是一个字符串，它储存在常量区，
//	// 对应的捕获 catch 的类型就是 const char* ，不能是 char* ，如果是 char* 会出现权限放大
//
//	/*catch (char* errmsg) { 
//		cout << errmsg << endl;
//	}*/
//	catch (const char* errmsg) { //catch 用来捕获异常
//		cout << errmsg << endl;
//	}
//	//catch (...) { //catch(...) 可以捕获任意类型的异常
//	//	cout << "unkown exception" << endl;
//	//}
//
//	catch (const string& errmsg) {
//		cout << errmsg << endl;
//	}
//	catch (...) { //只有抛出异常就会跳到catch
//		cout << "unkown exception" << endl;
//	}
//	system("pause");
//	return 0;
//}


//// ———————— 匹配原则2 ————————
//
//double Division(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//		throw "Division by zero condition!";
//	else
//		return ((double)a / (double)b);
//}
//void Func()
//{
//	int len, time;
//	cin >> len >> time;
//	cout << Division(len, time) << endl;
//}
//
//int main(){
//	try{// try 块中放置可能抛出异常的代码
//		try{
//			Func();
//		}
//		catch (const char* errmsg){//类型匹配，就近原则
//			cout << "1234" << " " << errmsg << endl;
//		}
//	}
//	catch (const char* errmsg){//类型匹配
//		cout << errmsg << endl;
//	}
//	catch (...){
//		cout << "Unkown Exception" << endl;
//	}
//	return 0;
//}






//// —————————— 异常匹配的调用规则 ——————————
//double f3() {
//	int a, b; cin >> a >> b;
//	if (b == 0) { // b = 0时抛出异常
//		throw "除 0 错误！";
//	}
//	else {
//		return (double)a / (double)b;
//	}
//}
//double f2() {
//	double res = f3();
//	cout << "f2()" << endl;
//	return res;
//}
//double f1() {
//	double res = 0; //记得初始化为0，不给初始化会Error
//	try {
//		res = f2();
//	}
//	catch (const char* a) {
//		cout << a << endl;
//	}
//	cout << "f1()" << endl;
//	return res;
//}
//int main() {
//	try {
//		cout << f1() << endl;
//	}
//	catch (...) {
//		cout << "unknow exception " << endl;
//	}
//	cout << "main" << endl;
//	system("pause");
//	return 0;
//}



// ———————— 异常的重新抛出 ————————
//void func1(){
//	try{
//		throw string("除0异常");
//	}
//	catch (const string& s){
//		//打印提示信息，简单处理
//		cout << s << endl;
//		// 重新抛出，让外层处理错误
//		throw;
//	}
//}
//int main(){
//	try{
//		func1();
//	}
//	catch (const string& s){
//		cout << "进行处理..." << s << endl;
//	}
//	catch (...){
//		cout << "Unkown Exception:未知异常" << endl;
//	}
//	system("pause");
//	return 0;
//}

// ———————— 直接让外层捕获异常进行处理

void func1(){
	throw string("除0异常");
}

//void func2(){
//	int* array = new int[10];
//	func1();
//	cout << "delete []" << array << endl;
//	delete[] array;
//	cout << "delete []" << array << endl;
//	cout << "内存已释放" << endl;
//}

//void func2(){
//	int* array = new int[10];
//	try{
//		func1();
//	}
//	catch (...){
//		cout << "delete []" << array << endl;
//		delete[] array;
//		throw;
//	}
//	//.
//	delete[] array;
//	cout << "array内存已释放" << endl;
//}
//
//int main(){
//	try{
//		func2();
//	}
//	catch (const string& s){
//		cout << s << ", 进行处理..." << endl;
//	}
//	catch (...){
//		cout << "Unkown Exception:未知异常" << endl;
//	}
//	system("pause");
//	return 0;
//}
//




// ————————  服务器开发中通常使用的异常继承体系 ————————

//基类
//异常
class Exception{
public:
	Exception(const string& errmsg, int id)
		:_errmsg(errmsg)
		, _id(id)
	{}

	virtual string what() const //虚函数为了搞多态
	{
		return _errmsg;
	}

	int getid() const{
		return _id;
	}
protected:
	string _errmsg;
	int _id;
};


//派生类
//数据库异常
class SqlException : public Exception{
public:
	SqlException(const string& errmsg, int id, const string& sql)
		:Exception(errmsg, id)
		, _sql(sql)
	{}

	virtual string what() const{
		string str = "SqlException:";
		str += _errmsg;
		str += "->";
		str += _sql;
		return str;
	}
private:
	const string _sql;
};

//网络异常
class CacheException : public Exception
{
public:
	CacheException(const string& errmsg, int id)
		:Exception(errmsg, id)
	{}

	virtual string what() const
	{
		string str = "CacheException:";
		str += _errmsg;
		return str;
	}
};

//缓存异常
class HttpServerException : public Exception{
public:
	HttpServerException(const string& errmsg, int id, const string& type)
		:Exception(errmsg, id)
		, _type(type)
	{}

	virtual string what() const{
		string str = "HttpServerException:";
		str += _type;
		str += ":";
		str += _errmsg;
		return str;
	}
private:
	const string _type;
};

void SQLMgr(){
	if (rand() % 7 == 0){
		throw SqlException("权限不足", 100, "select * from name = '张三'");
	}
	cout << "调用成功" << endl;
}

void CacheMgr(){
	if (rand() % 5 == 0){
		throw CacheException("权限不足", 100);
	}
	else if (rand() % 6 == 0){
		throw CacheException("数据不存在", 101);
	}
	SQLMgr();
}

void seedmsg(const string& s){
	//cout << "void seedmsg(const string& s)" << endl;

	//throw HttpServerException("网络不稳定，发送失败", 102, "put");

	if (rand() % 2 == 0){
		throw HttpServerException("网络不稳定，发送失败", 102, "put");
	}
	else if (rand() % 3 == 0){
		throw HttpServerException("你已经不是对象的好友，发送失败", 103, "put");
	}
	else{
		cout << "发送成功" << endl;
	}
}

void HttpServer(){
	/*if (rand() % 3 == 0)
	{
		throw HttpServerException("请求资源不存在", 100, "get");
	}
	else if (rand() % 4 == 0)
	{
		throw HttpServerException("权限不足", 101, "post");
	}*/

	// 失败以后，再重试3次
	for (size_t i = 0; i < 4; i++){
		try{
			seedmsg("今天一起看电影吧");
			break;
		}
		catch (const Exception& e){
			if (e.getid() == 102){
				if (i == 3)
					throw e;
				cout << "开始第" << i + 1 << "重试" << endl;
			}
			else{
				throw e;
			}
		}
	}

	CacheMgr();
}


//int main(){
//	while (1){
//		this_thread::sleep_for(chrono::seconds(1));
//		try {
//			HttpServer();
//		}
//		catch (const Exception& e) // 这里捕获父类对象就可以
//		{
//			using std::chrono::system_clock;
//			// 多态
//			system_clock::time_point today = system_clock::now();
//
//			std::time_t tt;
//			tt = system_clock::to_time_t(today);
//			std::cout << "todat is: " << ctime(&tt);
//
//			cout << ctime(&tt) << e.what() << endl << endl;
//		}
//		catch (...){
//			cout << "Unkown Exception" << endl;
//		}
//	}
//	return 0;
//}


// ———————— C++标准库的异常体系  —————— 
unsigned short test() {
	unsigned short a = 0;
	unsigned short b = 0;
	cin >> a >> b;
	if (a + b > 65535) {
		//c++标准库中的异常类
		throw overflow_error("overflow");
	}
	return a + b;
}

int main() {
	try {
		printf("%d\n", test());
	}
	//用基类捕捉
	catch (const exception& a) {
		cout << a.what() << endl;
	}
	catch (...) {
		cout << "unknow exception" << endl;
	}
	system("pause");
	return 0;
}







// —————————— 异常的重新抛出 ——————————

//double Division(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Division by zero condition!";
//	}
//	return (double)a / (double)b;
//}

//void Func()
//{
//	// 这里可以看到如果发生除0错误抛出异常，另外下面的array没有得到释放。
//	// 所以这里捕获异常后并不处理异常，异常还是交给外面处理，这里捕获了再
//	// 重新抛出去。
//	int* array = new int[10];
//
//	try 
//	{
//		int len, time;
//		cin >> len >> time;
//		cout << Division(len, time) << endl;
//	}
//	catch (...)
//	{
//		cout << "delete []" << array << endl;
//		delete[] array;
//
//		throw; // 异常重新抛出，捕获到什么抛出什么
//	}
//
//	// ...
//	cout << "delete []" << array << endl;
//	delete[] array;
//}

//void Func()
//{
//	// 这里可以看到如果发生除0错误抛出异常，另外下面的array没有得到释放。
//	// 所以这里捕获异常后并不处理异常，异常还是交给外面处理，这里捕获了再
//	// 重新抛出去。
//	// 
//	// 更好解决方案是智能指针
//	int* array1 = new int[10];
//	int* array2 = new int[10];   // 抛异常呢
//
//	try
//	{
//		int len, time;
//		cin >> len >> time;
//		cout << Division(len, time) << endl;
//	}
//	catch (...)
//	{
//		cout << "delete []" << array1 << endl;
//		cout << "delete []" << array2 << endl;
//
//		delete[] array1;
//		delete[] array2;
//
//		throw; // 异常重新抛出，捕获到什么抛出什么
//	}
//
//	// ...
//	cout << "delete []" << array1 << endl;
//	delete[] array1;
//
//	cout << "delete []" << array2 << endl;
//	delete[] array2;
//}



//struct A
//{
//	~A() noexcept
//	{
//		cout << "~A()" << endl;
//	}
//
//	int _a1 = 0;
//	int _a2 = 0;
//};
//
////智能指针
//template<class T>
//class SmartPtr
//{
//public:
//	// RAII
//	SmartPtr(T* ptr)
//		:_ptr(ptr)
//	{}
//
//	~SmartPtr()
//	 {
//		delete _ptr;
//	}
//
//	// 重载运算符，模拟指针的行为
//	T& operator*()
//	{
//		return *_ptr;
//	}
//
//	T* operator->()
//	{
//		return _ptr;
//	}
//private:
//	T* _ptr;
//};
//
//unique_ptr<A> func()
//{
//	unique_ptr<A> sp(new A);
//	return sp;
//}
//
//void Func()
//{
//	// 更好解决方案是智能指针
//	shared_ptr<A> sp1(new A);
//	shared_ptr<A> sp2(new A);
//	sp1->_a1++;
//	sp1->_a2++;
//
//	//没有自己写拷贝的话，就是调用默认的拷贝，属于浅拷贝，导致析构多次
//	shared_ptr<A> sp3(sp1); 
//
//	int len, time;
//	cin >> len >> time;
//	cout << Division(len, time) << endl;
//}
//
//int main()
//{
//	try
//	{
//		Func();
//	}
//	catch (const char* errmsg)
//	{
//		cout << errmsg << endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	catch (...)
//	{
//		cout << "未知异常" << endl;
//	}
//
//	return 0;
//}